home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2a.lha / p4-1.2a / alog / mergelogs.c < prev    next >
C/C++ Source or Header  |  1992-10-19  |  9KB  |  502 lines

  1. /*
  2.  * merge.c:  Program to take mutiple strand format logfiles, sort them,
  3.  *           merge them, and prepend information to the final logfile.
  4.  *
  5.  * Algorithm:
  6.  *     Copy all the negative events at the beginning of the logfiles to a
  7.  *       temporary header file.
  8.  *     Use the unix sort command to sort all the logfiles.
  9.  *     Analyze the data, ignoring all events that are not > 0.
  10.  *     Print to stdout the results of the analyzation, the header file,
  11.  *       and the sorted log entries.
  12.  *
  13.  *    Modified Summer 1990 by James Arthur Kohl
  14.  *        to combine count collection more efficiently.
  15.  *
  16.  *        Now it's REAL fast!
  17.  */
  18. #include <stdio.h>
  19. #include <ctype.h>           /* for calling isdigit()             */
  20. #include "alog_evntdfs.h"       /* Logfile definitions */
  21.  
  22. #define FALSE 0
  23. #define TRUE !FALSE
  24. #define MAX(x,y)    ( (x) > (y) ? (x) : (y) )
  25.  
  26. #define C_DATA_LEN 50
  27.  
  28. #define DO_NEGATIVE 1
  29. #define IGNORE_NEGATIVE 2
  30.  
  31. struct log_entry
  32. {
  33.     int proc_id;
  34.     int task_id;
  35.     int event;
  36.     int i_data;
  37.     char c_data[C_DATA_LEN];
  38.     int time_slot;
  39.     unsigned long time;
  40. };
  41.  
  42. struct list_struct
  43. {
  44.     struct log_entry entry;
  45.     struct list_struct *next;
  46. } *log_table;
  47.  
  48. struct list_struct *log_ptr;
  49.  
  50. int entry_tot;
  51.  
  52. main(argc,argv)
  53. int argc;
  54. char *argv[];
  55. {
  56.     FILE *headerfp;
  57.  
  58.     char headerfile[255];
  59.  
  60.     int pid;
  61.  
  62.     if ( argc <= 1 ) 
  63.         usage();
  64.  
  65.     pid = getpid();
  66.  
  67.     sprintf(headerfile,"/usr/tmp/log.header.%d",pid);
  68.  
  69.     if ( (headerfp=fopen(headerfile,"w")) == NULL )
  70.     {
  71.         fprintf(stderr,"merge: unable to create temp file %s.\n",headerfile);
  72.         exit(0);
  73.     }
  74.  
  75.     combine_files(argc,argv,headerfp);
  76.  
  77.     if ( (headerfp=fopen(headerfile,"r")) == NULL )
  78.     {
  79.         fprintf(stderr,"merge: unable to read temp file %s.\n",headerfile);
  80.         exit(0);
  81.     }
  82.  
  83.     fprintf(stderr,"Analyzing.\n");
  84.     analyze(headerfp);
  85.  
  86.     fclose(headerfp);
  87.     unlink(headerfile); 
  88.     free(headerfile);
  89. } /* main */
  90.  
  91.  
  92. combine_files(argc,argv,headerfp)
  93. int argc;
  94. char *argv[];
  95. FILE *headerfp;
  96. {
  97.     FILE *in;
  98.  
  99.     struct list_struct **files;
  100.     struct list_struct *last;
  101.     struct list_struct *ptr;
  102.  
  103.     struct log_entry *entry;
  104.  
  105.     unsigned long min_time;
  106.  
  107.     int min_event;
  108.     int min_slot;
  109.     int min;
  110.  
  111.     int all_eof;
  112.     int eof_flag;
  113.     int negflag;
  114.     int num;
  115.     int i;
  116.  
  117.     num = argc - 1;
  118.  
  119.     if ( (files=(struct list_struct **)
  120.         malloc(num * sizeof(struct list_struct *))) == NULL )
  121.     {
  122.         fprintf(stderr,"merge: unable to allocate input data array.\n");
  123.         exit(0);
  124.     }
  125.  
  126.     for ( i=0 ; i < num ; i++ )
  127.     {
  128.         fprintf(stderr,"Reading %s\n",argv[i+1]);
  129.  
  130.         if ( (in=fopen(argv[i+1],"r")) == NULL )
  131.         {
  132.             fprintf(stderr,"merge: unable to read data file %s.\n",argv[i+1]);
  133.             exit(0);
  134.         }
  135.  
  136.         if ( (files[i]=(struct list_struct *)
  137.             malloc(sizeof(struct list_struct))) == NULL )
  138.         {
  139.             fprintf(stderr,"merge: unable to allocate list struct.\n");
  140.             exit(0);
  141.         }
  142.  
  143.         ptr = files[i];
  144.  
  145.         last = NULL;
  146.  
  147.         do
  148.         {
  149.             read_logentry(in,&(ptr->entry),DO_NEGATIVE);
  150.  
  151.             if ( !(eof_flag=feof(in)) )
  152.             {
  153.                 if ( (ptr->next=(struct list_struct *)
  154.                     malloc(sizeof(struct list_struct))) == NULL )
  155.                 {
  156.                     fprintf(stderr,"merge: unable to allocate list struct.\n");
  157.                     exit(0);
  158.                 }
  159.  
  160.                 last = ptr;
  161.  
  162.                 ptr = ptr->next;
  163.             }
  164.  
  165.             else
  166.             {
  167.                 if ( last != NULL )
  168.                     last->next = NULL;
  169.  
  170.                 else
  171.                     files[i] = NULL;
  172.  
  173.                 free(ptr);
  174.                 ptr = NULL;
  175.             }
  176.         }
  177.         while ( !eof_flag );
  178.  
  179.         fclose(in);
  180.     }
  181.  
  182.     fprintf(stderr,"Sorting.\n");
  183.  
  184.     all_eof = 0;
  185.  
  186.     do
  187.     {
  188.         negflag = 0;
  189.  
  190.         for ( i=0 ; i < num ; i++ )
  191.         {
  192.             if ( files[i] == NULL )
  193.                 continue;
  194.  
  195.             entry = &(files[i]->entry);
  196.  
  197.             if ( entry->event < 0 )
  198.             {
  199.                 negflag++;
  200.  
  201.                 fprintf(headerfp,"%d %d %d %d %d %lu %s\n",entry->event,
  202.                     entry->proc_id,entry->task_id,entry->i_data,
  203.                     entry->time_slot,entry->time,entry->c_data);
  204.  
  205.                 files[i] = files[i]->next;
  206.  
  207.                 if ( files[i] == NULL )
  208.                     all_eof++;
  209.             }
  210.         }
  211.     }
  212.     while ( negflag && all_eof < num );
  213.  
  214.     fclose(headerfp);
  215.  
  216.     log_table = log_ptr = NULL;
  217.  
  218.     entry_tot = 0;
  219.  
  220.     while ( all_eof < num )
  221.     {
  222.         min_event = 0;
  223.         min_time = 0;
  224.         min_slot = 0;
  225.  
  226.         min = -1;
  227.  
  228.         for ( i=0 ; i < num ; i++ )
  229.         {
  230.             if ( files[i] == NULL )
  231.                 continue;
  232.  
  233.             entry = &(files[i]->entry);
  234.  
  235.             if (
  236.                 (entry->time_slot == min_slot && entry->time < min_time)
  237.                 || entry->time_slot < min_slot
  238.                 || min == -1
  239.                 || (entry->time_slot == min_slot && entry->time == min_time
  240.                     && entry->event < min_event)
  241.                 )
  242.             {
  243.                 min_event = entry->event;
  244.                 min_time = entry->time;
  245.                 min_slot = entry->time_slot;
  246.  
  247.                 min = i;
  248.             }
  249.         }
  250.  
  251.         if ( log_ptr == NULL )
  252.         {
  253.             log_table = log_ptr = files[min];
  254.  
  255.             files[min] = files[min]->next;
  256.         }
  257.  
  258.         else
  259.         {
  260.             log_ptr->next = files[min];
  261.  
  262.             files[min] = files[min]->next;
  263.  
  264.             log_ptr = log_ptr->next;
  265.         }
  266.  
  267.         log_ptr->next = NULL;
  268.  
  269.         entry_tot++;
  270.  
  271.         if ( files[min] == NULL )
  272.             all_eof++;
  273.     }
  274.  
  275.     fprintf(stderr, "  %d total entries\n", entry_tot);
  276. }
  277.  
  278.  
  279. usage()
  280. {
  281.     fprintf(stderr,"mergelogs: mergelogs infile1 infile2 ...\n");
  282.     fprintf(stderr,"  writes to stdout\n");
  283.  
  284.     exit(0);
  285. }
  286.  
  287.  
  288. /* analyze:  At this point, we have one large sorted file called :tname:.
  289.  *           We want to prepend certain data to it.
  290.  *           We also want to prepend the data from the file pointed to
  291.  *             by :headerfp:.
  292.  *           See balance:/usr/local/trace/README for info.
  293.  *           
  294.  */
  295. analyze(headerfp)
  296. FILE *headerfp;
  297. {
  298.     struct log_entry *entry;
  299.  
  300.     int proc_tot, task_tot, time_slot_tot, event_tot;
  301.     int i;
  302.  
  303.     get_counts(&proc_tot,&task_tot,&event_tot,&time_slot_tot);
  304.  
  305.     fprintf(stderr, "  %d separate processors\n",  proc_tot);
  306.     fprintf(stderr, "  %d separate tasks\n",  task_tot);
  307.     fprintf(stderr, "  %d event types\n", event_tot);
  308.  
  309.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_EVENTS,0,0,entry_tot,0,0L);
  310.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_PROCS,0,0,proc_tot,0,0L);
  311.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_TASKS,0,0,task_tot,0,0L);
  312.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_EVTYPES,0,0,event_tot,0,0L); 
  313.     fprintf(stdout,"%d %d %d %d %d %lu\n",START_TIME,0,0,0,0,
  314.         log_table->entry.time);
  315.     fprintf(stdout,"%d %d %d %d %d %lu\n",END_TIME,0,0,0,0,
  316.         log_ptr->entry.time);
  317.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_CYCLES,0,0,time_slot_tot,0,0L);
  318.  
  319.     dump_header(headerfp);
  320.  
  321.     log_ptr = log_table;
  322.  
  323.     while ( log_ptr != NULL )
  324.     {
  325.         entry = &(log_ptr->entry);
  326.  
  327.         fprintf(stdout,"%d %d %d %d %d %lu  %s\n",entry->event, 
  328.             entry->proc_id,entry->task_id,entry->i_data,
  329.             entry->time_slot,entry->time,entry->c_data);
  330.     
  331.         log_ptr = log_ptr->next;
  332.     }
  333. } /* analyze */  
  334.  
  335.  
  336. dump_header(headerfp)
  337. FILE *headerfp;
  338. {
  339.     char buf[512];
  340.     int len;
  341.  
  342.     do
  343.     {
  344.         if ( len=fread(buf,sizeof(char),512,headerfp) )
  345.             fwrite(buf,sizeof(char),len,stdout);
  346.     }
  347.     while ( !feof(headerfp) && len );
  348. } /* dump_header */
  349.     
  350.  
  351. read_logentry(fp,table,do_negs)
  352. FILE *fp;
  353. struct log_entry *table;
  354. int do_negs;
  355. {
  356.     char buf[81];
  357.     char *cp;
  358.  
  359.     int i;
  360.  
  361.     do
  362.     {    
  363.         fscanf(fp,"%d %d %d %d %d %lu",
  364.             &(table->event),&(table->proc_id),&(table->task_id),
  365.             &(table->i_data),&(table->time_slot),&(table->time));
  366.  
  367.         cp = table->c_data;
  368.  
  369.         i = 0;
  370.  
  371.         do
  372.         {
  373.             fscanf(fp,"%c",cp);
  374.         }
  375.         while ( *cp == ' ' || *cp == '\t' );
  376.  
  377.         i++;
  378.  
  379.         while ( *cp != '\n' && i < C_DATA_LEN )
  380.         {
  381.             fscanf(fp,"%c",++cp);
  382.  
  383.             i++;
  384.         }
  385.  
  386.         *cp = '\0';
  387.  
  388.         /*
  389.         if ( !feof(fp) && table->event == 0 )
  390.             fprintf(stderr,"0 reading in.\n");
  391.         */
  392.     }
  393.     while( table->event < 0 && do_negs == IGNORE_NEGATIVE && !feof(fp) );
  394. }
  395.  
  396.  
  397. get_counts(ptot,ttot,etot,tstot)
  398. int *ptot,*ttot,*etot,*tstot;
  399. {
  400.     struct list_struct *ptr;
  401.  
  402.     struct log_entry *entry;
  403.     struct log_entry *last;
  404.  
  405.     int *p, *t, *e;
  406.  
  407.     int flag;
  408.     int val;
  409.     int i,j;
  410.  
  411.     if ( (p=(int *)malloc(sizeof(int) * entry_tot)) == NULL )
  412.     {
  413.         fprintf(stderr,"Not enough memory.\n");
  414.         exit(0);
  415.     }
  416.  
  417.     if ( (t=(int *)malloc(sizeof(int) * entry_tot)) == NULL )
  418.     {
  419.         fprintf(stderr,"Not enough memory.\n");
  420.         exit(0);
  421.     }
  422.  
  423.     if ( (e=(int *)malloc(sizeof(int) * entry_tot)) == NULL )
  424.     {
  425.         fprintf(stderr,"Not enough memory.\n");
  426.         exit(0);
  427.     }
  428.  
  429.     for ( i=0 ; i < entry_tot ; i++ )
  430.     {
  431.         p[i] = t[i] = e[i] = 0;
  432.     }
  433.  
  434.     *ptot = *ttot = *etot = 0;
  435.  
  436.     *tstot = 1;
  437.  
  438.     ptr = log_table;
  439.  
  440.     last == NULL;
  441.  
  442.     while ( ptr != NULL )
  443.     {
  444.         entry = &(ptr->entry);
  445.  
  446.         flag = 0;
  447.  
  448.         val = entry->proc_id;
  449.  
  450.         for ( j=0 ; j < *ptot && !flag ; j++ )
  451.         {
  452.             if ( p[j] == val )
  453.                 flag++;
  454.         }
  455.  
  456.         if ( !flag )
  457.         {
  458.             p[(*ptot)++] = val;
  459.         }
  460.  
  461.         flag = 0;
  462.  
  463.         val = entry->task_id;
  464.  
  465.         for ( j=0 ; j < *ttot && !flag ; j++ )
  466.         {
  467.             if ( t[j] == val )
  468.                 flag++;
  469.         }
  470.  
  471.         if ( !flag )
  472.         {
  473.             t[(*ttot)++] = val;
  474.         }
  475.  
  476.         flag = 0;
  477.  
  478.         val = entry->event;
  479.  
  480.         for ( j=0 ; j < *etot && !flag ; j++ )
  481.         {
  482.             if ( e[j] == val )
  483.                 flag++;
  484.         }
  485.  
  486.         if ( !flag )
  487.         {
  488.             e[(*etot)++] = val;
  489.         }
  490.  
  491.                 /* printf("tstot=%d *tstot=%d\n",tstot,*tstot); */
  492.         if ( (last != NULL) && (entry->time_slot != last->time_slot) )
  493.                         *tstot = *tstot + 1;
  494.             /*  (*tstot)++;  */
  495.  
  496.         last = entry;
  497.  
  498.         ptr = ptr->next;
  499.     }
  500.         return(0);
  501. }
  502.